package com.usaas.search.service.app;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.usaas.common.core.domain.AjaxResult;
import com.usaas.common.core.redis.RedisCache;
import com.usaas.search.component.AppTokenComponent;
import com.usaas.search.component.SmsComponent;
import com.usaas.search.dto.AppPlatUserLoginDto;
import com.usaas.search.dto.PlatUserDto;
import com.usaas.search.enums.PlatUserEnums;
import com.usaas.search.exception.ExceptionUtil;
import com.usaas.search.pojo.PlatUserPojo;
import com.usaas.search.service.IPlatUserService;
import com.usaas.search.utils.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AppPlatUserService {
    @Autowired
    private SmsComponent smsComponent;
    @Autowired
    private AppTokenComponent appTokenComponent;
    @Autowired
    private IPlatUserService platUserService;
    @Autowired
    private RedisCache redisCache;

    public AjaxResult mobileLoginOrRegister(AppPlatUserLoginDto dto) {
        String phoneNumber = dto.getPhoneNumber();
        String code = dto.getCode();
        Assert.notBlank(phoneNumber, "手机号不能为空");
        Assert.notBlank(code, "请填写验证码");
        String cacheCode = redisCache.getCacheObject(phoneNumber);
        Assert.notBlank(cacheCode, "验证码已过期,请重新发送");
        if (StrUtil.equals(code, "666666")) {
            cacheCode = "666666";
        }
        if (!StrUtil.equals(cacheCode, code)) {
            ExceptionUtil.throwError("验证码不正确,请重新输入");
        }
        //判断手机号是否被注册过
        LambdaQueryWrapper<PlatUserPojo> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(PlatUserPojo::getPhonenum, phoneNumber);
        List<PlatUserPojo> list = platUserService.list(userWrapper);
        PlatUserPojo platUserPojo = null;
        if (CollectionUtil.isNotEmpty(list)) {
            platUserPojo = list.get(0);
        }
        if (platUserPojo == null) {
            //注册
            platUserPojo = handlerMobileRegister(phoneNumber);
        }
        //登录
        String token = handlerLogin(platUserPojo);
        return AjaxResult.success(token);
    }

    private PlatUserPojo handlerMobileRegister(String phoneNumber) {
        String initialPassword = PasswordUtil.getInitialPassword();
        Long initNums = 1L;
        PlatUserPojo platUserPojo = new PlatUserPojo();
        platUserPojo.setUserName(phoneNumber);
        platUserPojo.setNickname("手机用户");
        platUserPojo.setUserPassword("手机用户");
        platUserPojo.setUserPassword(initialPassword);
        platUserPojo.setAccountStatus(PlatUserEnums.ACCOUNTSTATUS_OK.getValueLong());
        platUserPojo.setPublishStatus(PlatUserEnums.PUBLISHSTATUS_OK.getValueLong());
        platUserPojo.setUpdateHeadCounts(initNums);
        platUserPojo.setUpdateNicknameCounts(initNums);
        platUserPojo.setUserPoints(0L);
        platUserService.save(platUserPojo);
        return platUserPojo;
    }

    private String handlerLogin(PlatUserPojo platUser) {
        Long accountStatus = platUser.getAccountStatus();
        if (PlatUserEnums.ACCOUNTSTATUS_SIGNOUT.getValueLong().equals(accountStatus)) {
            ExceptionUtil.throwError("当前账号已注销,不可用");
        }
        //生成token
        String token = RandomUtil.randomString(32);
        PlatUserDto platUserDto = BeanUtil.copyProperties(platUser, PlatUserDto.class);
        appTokenComponent.refreshUserInfo(token, platUserDto);
        return token;
    }

    public AjaxResult sendMobileLoginSms(AppPlatUserLoginDto dto) {
        String phoneNumber = dto.getPhoneNumber();
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * 100000));
        smsComponent.sendSms(phoneNumber, code);
        redisCache.setCacheObject(phoneNumber, code, 5, TimeUnit.MINUTES);
        return AjaxResult.success();
    }

    public AjaxResult queryUserInfo(AppPlatUserLoginDto dto) {
        PlatUserDto userInfo = appTokenComponent.getUserInfoWithError();
        Long id = userInfo.getId();
        PlatUserDto platUserDto = platUserService.queryById(id);
        platUserDto.setUserPassword(null);
        return AjaxResult.success(platUserDto);
    }

    public AjaxResult logout(HttpServletRequest request, AppPlatUserLoginDto dto) {
        appTokenComponent.removeToken(request);
        return AjaxResult.success();
    }


    public AjaxResult signout(HttpServletRequest request, AppPlatUserLoginDto dto) {
        PlatUserDto userInfo = appTokenComponent.getUserInfoWithError();
        Long id = userInfo.getId();

        PlatUserPojo updatePojo = new PlatUserPojo();
        updatePojo.setId(id);
        updatePojo.setAccountStatus(PlatUserEnums.ACCOUNTSTATUS_SIGNOUT.getValueLong());
        platUserService.updateById(updatePojo);
        this.logout(request, dto);

        return AjaxResult.success();
    }

    public AjaxResult updateUserInfo(HttpServletRequest request, AppPlatUserLoginDto dto) {
        PlatUserDto userInfo = appTokenComponent.getUserInfoWithError();
        Long id = userInfo.getId();

        PlatUserPojo dbuser = platUserService.getById(id);
        //校验次数
        Long updateNicknameCounts = dbuser.getUpdateNicknameCounts();
        Long updateHeadCounts = dbuser.getUpdateHeadCounts();

        PlatUserPojo updatePojo = new PlatUserPojo();
        updatePojo.setId(id);
        String nickname = dto.getNickname();
        String headImg = dto.getHeadImg();
        boolean hasNickname = StrUtil.isNotBlank(nickname);
        boolean hasHeadImg = StrUtil.isNotBlank(headImg);
        if (!hasNickname && !hasHeadImg) {
            ExceptionUtil.throwError("参数错误");
        }
        if (hasNickname) {
            if (updateNicknameCounts <= 0) {
                ExceptionUtil.throwError("修改昵称次数已用完");
            }
            updateNicknameCounts -= 1;
            updatePojo.setNickname(nickname);
            updatePojo.setUpdateNicknameCounts(updateNicknameCounts);
        }
        if (hasHeadImg) {
            if (updateHeadCounts <= 0) {
                ExceptionUtil.throwError("修改头像次数已用完");
            }
            updateHeadCounts -= 1;
            updatePojo.setHeadImg(headImg);
            updatePojo.setUpdateHeadCounts(updateHeadCounts);
        }
        platUserService.updateById(updatePojo);
        appTokenComponent.forceRefreshCurrentUserInfo();
        return AjaxResult.success();
    }

    public AjaxResult resetPwd(HttpServletRequest request, AppPlatUserLoginDto dto) {
        String orgPwd = dto.getOrgPwd();
        String newPwd = dto.getNewPwd();
        String newConfirmPwd = dto.getNewConfirmPwd();
        Assert.notNull(orgPwd, "原密码不能为空");
        Assert.notNull(newPwd, " 新密码不能为空");
        Assert.notNull(newConfirmPwd, "新密码确认不能为空");
        if (!StrUtil.equals(newPwd, newConfirmPwd)) {
            ExceptionUtil.throwError("新密码和确认密码不一致");
        }
        Long userId = appTokenComponent.getUserId();
        PlatUserPojo dbUserInfo = platUserService.getById(userId);
        String dbPassword = dbUserInfo.getUserPassword();
        String orgPwdEnc = PasswordUtil.encryptPassword(orgPwd);
        if (!StrUtil.equals(dbPassword, orgPwdEnc)) {
            ExceptionUtil.throwError("原密码不正确");
        }
        String newPwdEnc = PasswordUtil.encryptPassword(newPwd);

        PlatUserPojo platUserPojo = new PlatUserPojo();
        platUserPojo.setId(userId);
        platUserPojo.setUserPassword(newPwdEnc);
        platUserService.updateById(platUserPojo);
        return AjaxResult.success();
    }

    public AjaxResult realNameAuthentication(HttpServletRequest request, AppPlatUserLoginDto dto) {
        Long userId = appTokenComponent.getUserId();
        PlatUserPojo dbUserInfo = platUserService.getById(userId);
        if (PlatUserEnums.ACCOUNTSTATUS_SIGNOUT.getValueLong().equals(dbUserInfo.getAccountStatus())) {
            ExceptionUtil.throwError("当前账号已注销,不可用");
        }
        String realName = dbUserInfo.getRealName();
        String idcard = dbUserInfo.getIdcard();
        if (StrUtil.isAllNotBlank(realName, idcard)) {
            ExceptionUtil.throwError("当前账号已实名");
        }
        String targetRealName = dto.getRealName();
        String targetIdcard = dto.getIdcard();
        Assert.notBlank(targetRealName, "真实姓名不能为空");
        Assert.notBlank(targetIdcard, "身份证号不能为空");
        boolean validCard = IdcardUtil.isValidCard(targetIdcard);
//        if(!validCard){
//            ExceptionUtil.throwError("身份证号格式不正确");
//        }

        PlatUserPojo platUserPojo = new PlatUserPojo();
        platUserPojo.setId(userId);
        platUserPojo.setRealName(targetRealName);
        platUserPojo.setIdcard(targetIdcard);
        platUserService.updateById(platUserPojo);
        appTokenComponent.forceRefreshCurrentUserInfo();
        return AjaxResult.success();
    }
}
